package mc.support.util;

import mc.support.support.function.Closure;
import org.apache.commons.lang.StringUtils;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;

/**
 * Created with IntelliJ IDEA. <br/>
 * Author: francis Yun    <br/>
 * Date: 2013-12-09  <br/>
 */
public final class PlainUtil {
    private PlainUtil() {}

    public static String connectToStr(Object...oo) {
        if ( null == oo || 0 == oo.length ) {
            return "";
        }
        StringBuilder s = new StringBuilder();
        for ( int i=0; i < oo.length; i++ ) {
            s.append( oo[i] );
        }
        return s.toString();
    }

    public static boolean isContain(String whole, String part) {
        if ( StringUtils.isNotBlank(whole) ) {
            if ( !StringUtils.isNotBlank(part) ) {
                return true;
            }
            whole = whole.toLowerCase();
            part = part.toLowerCase();
            return whole.indexOf( part ) >= 0;
        } else {
            return !StringUtils.isNotBlank( part );
        }
    }

    public static Set<String> toStringSet( final Set<Long> s ) {
        return null != s ? new HashSet<String>() {
            {
                for ( Long l : s ) {
                    add( l.toString() );
                }
            }
        } : null;
    }

    public static <P,R> Map<R, Set<P>> buildMapSetByList(List<P> list, Closure<R, P> func) {
        if ( null == list || null == func ) {
            return null;
        }

        Map<R,Set<P>> map = new HashMap<>();
        for ( P p : list ) {
            R r = func.call( p );
            Set<P> s = map.get( r );
            if ( null == s ) {
                s = new HashSet<>();
                map.put( r, s );
            }
            s.add( p );
        }

        return map;
    }

    public static <P,R> Map<R, List<P>> buildMapListByList(List<P> list, Closure<R, P> func) {
        if ( null == list || null == func ) {
            return null;
        }

        Map<R,List<P>> map = new HashMap<>();
        for ( P p : list ) {
            R r = func.call( p );
            List<P> l = map.get( r );
            if ( null == l ) {
                l = new ArrayList<>();
                map.put( r, l );
            }
            l.add( p );
        }

        return map;
    }

    public static <P,R> Map<R, P> buildMapByList(List<P> list, Closure<R, P> func) {
        if ( null == list || null == func ) {
            return null;
        }

        Map<R,P> map = new HashMap<>();
        for ( P p : list ) {
            R r = func.call( p );
            map.put( r, p );
        }

        return map;
    }

    public static <P,R> Set<R> getInfoSet(List<P> list, Closure<R,P> func) {
        if ( null == list || null == func ) {
            return null;
        }

        Set<R> s = new HashSet<>();
        for ( P p : list ) {
            R r = func.call( p );
            if ( null != r ) {
                s.add( r );
            }
        }

        return s;
    }

    public static <P> List<P> filterList(List<P> list, Closure<Boolean, P> func) {
        if ( null == list || null == func ) {
            return null;
        }

        List<P> filterd = new ArrayList<>();
        for ( P p : list ) {
            Boolean include = func.call( p );
            if ( null != include && include ) {
                filterd.add( p );
            }
        }

        return filterd;
    }

    public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        throwable.printStackTrace(pw);
        return sw.getBuffer().toString();
    }

}
